// ===============================================
// PermissionUtils
//
// Create by Will on 2020/11/6 2:28 PM
// Copyright @Will.All rights reserved.
// ===============================================

import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';

import '../core_intl/core_kit_localizations.dart';
import '../toast.dart';
import 'dialog_utils.dart';

class PermissionUtils {
  PermissionUtils._internal();

  static Future<void> requestPermissions({
    required BuildContext context,
    required List<Permission> permissions,
    TextSpan? title,
    TextSpan? content,
    TextSpan? appSettingsTitle,
    TextSpan? appSettingsContent,
    VoidCallback? onAllGranted,
    VoidCallback? onDisallow,
    VoidCallback? onOpenAppSettings,
  }) async {
    if (await permissions.isAllGranted()) {
      return onAllGranted?.call();
    } else if (await permissions.shouldOpenAppSettings()) {
      if (context.mounted) {
        return showOpenAppSettingsDialog(
          context: context,
          title: appSettingsTitle,
          content: appSettingsContent,
          onProcessed: onOpenAppSettings,
          onDisallow: onDisallow,
        );
      }
      return;
    } else {
      if (context.mounted) {
        return showPermissionsDialog(
          context: context,
          title: title,
          content: content,
          permissions: permissions,
          onProcessed: () async {
            final isAllGranted = await permissions.isAllGranted();
            if (isAllGranted) {
              onAllGranted?.call();
            } else {
              onDisallow?.call();
            }
          },
          onDisallow: onDisallow,
        );
      }
      return;
    }
  }

  static Future<void> showPermissionsDialog({
    required BuildContext context,
    TextSpan? title,
    TextSpan? content,
    required List<Permission> permissions,
    VoidCallback? onProcessed,
    VoidCallback? onDisallow,
    bool useRootNavigator = true,
    RouteSettings? routeSettings,
  }) async {
    return showAllowDialog(
      context: context,
      title: title ??
          TextSpan(text: CoreKitS.of(context).dialogTitlePermissionRequired),
      content: content,
      onAllow: () async {
        // 去申请权限
        await permissions.request();
        onProcessed?.call();
      },
      onDisallow: onDisallow,
      useRootNavigator: useRootNavigator,
      routeSettings: routeSettings,
    );
  }

  static Future<void> showOpenAppSettingsDialog({
    required BuildContext context,
    TextSpan? title,
    TextSpan? content,
    VoidCallback? onProcessed,
    VoidCallback? onDisallow,
    bool useRootNavigator = true,
    RouteSettings? routeSettings,
  }) {
    return showAllowDialog(
      context: context,
      title: title ??
          TextSpan(text: CoreKitS.of(context).dialogTitlePermissionSettings),
      content: content,
      onAllow: () async {
        final isOpened = await openAppSettings();
        if (!isOpened) {
          toastFailure(CoreKitS.of(context).errorOpenAppSettings);
        }
        onProcessed?.call();
      },
      onDisallow: onDisallow,
      useRootNavigator: useRootNavigator,
      routeSettings: routeSettings,
    );
  }

  static Future<void> showAllowDialog({
    required BuildContext context,
    TextSpan? title,
    TextSpan? content,
    VoidCallback? onAllow,
    VoidCallback? onDisallow,
    bool useRootNavigator = true,
    RouteSettings? routeSettings,
  }) {
    return DialogUtils.showAlert(
      context: context,
      title: title,
      content: Center(
        child: Text.rich(
          content!,
          textAlign: TextAlign.start,
        ),
      ),
      actionsBuilder: (context) => <Widget>[
        CupertinoDialogAction(
          onPressed: () {
            Navigator.pop(context);
            onDisallow?.call();
          },
          child: Text(CoreKitS.of(context).btnDisallow),
        ),
        CupertinoDialogAction(
          onPressed: () {
            Navigator.pop(context);
            onAllow?.call();
          },
          isDefaultAction: true,
          child: Text(CoreKitS.of(context).btnAllow),
        ),
      ],
      useRootNavigator: useRootNavigator,
      routeSettings: routeSettings,
    );
  }
}

extension PermissionListActions on List<Permission> {
  Future<bool> isAllGranted() async {
    for (final permission in this) {
      final isGranted = await permission.isGranted;
      if (!isGranted) {
        return false;
      }
    }
    return true;
  }

  Future<bool> shouldOpenAppSettings() async {
    for (final permission in this) {
      final status = await permission.status;
      switch (status) {
        case PermissionStatus.granted:
        case PermissionStatus.limited:
          continue;
        case PermissionStatus.denied:
          if (await permission.shouldShowRequestRationale) {
            continue;
          } else {
            return true;
          }
        case PermissionStatus.restricted:
        case PermissionStatus.permanentlyDenied:
          return true;
        case PermissionStatus.provisional:
          break;
      }
    }
    return false;
  }
}
